// syscall_monitor.bpf.c
// 系统调用监控程序
#define __TARGET_ARCH_x86
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_endian.h>

#include "syscall_monitor.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";

// struct trace_event_raw_sched_process_exit;
// struct trace_event_raw_sched_wakeup;
// struct trace_event_raw_softirq_entry;
// struct trace_event_raw_softirq_exit;
// struct trace_event_raw_page_fault_user;
// struct trace_event_raw_page_fault_kernel;

// struct trace_event_raw_sys_enter;
// struct trace_event_raw_sys_exit;
// struct trace_event_raw_sched_switch;
// struct trace_event_raw_sched_process_fork;
// struct trace_event_raw_irq_handler_entry;
// struct trace_event_raw_irq_handler_exit;

// 存储目标进程PID的全局变量 - 在BPF程序中定义
int my_pid SEC(".bss") = 0;

// 存储进程详细信息的映射
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, __u32);  // PID
    __type(value, struct process_info);
} process_map SEC(".maps");

// 简单计数统计 (保持原有的简单统计)
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, __u32);  // PID
    __type(value, __u64); // syscall count
} syscall_count SEC(".maps");

// 通用的系统调用进入时间戳映射
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);  // 足够大以支持多个并发进程
    __type(key, __u64);         // 组合键: 高32位为PID，低32位为系统调用号
    __type(value, __u64);       // 进入时间戳
} syscall_enter_time SEC(".maps");

// Per-CPU 映射用于存储临时的大结构体变量
struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct process_info);
} process_info_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct security_event);
} security_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct syscall_event);
} syscall_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct lock_contention_event);
} lock_contention_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct interrupt_event);
} interrupt_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct container_event);
} container_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct process_lifecycle_event);
} process_lifecycle_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct network_connection);
} network_connection_event_heap SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct network_traffic);
} network_traffic_stat_heap SEC(".maps");

// 条件编译：Perf Event Array Maps（仅在实时输出模式下定义）
#ifdef OUTPUT_MODE_PERF_EVENT

#define DEFINE_PERF_EVENT_MAP(name) \
struct { \
    __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); \
    __uint(key_size, sizeof(__u32)); \
    __uint(value_size, sizeof(__u32)); \
} name SEC(".maps");

DEFINE_PERF_EVENT_MAP(syscall_events)
DEFINE_PERF_EVENT_MAP(process_events)
DEFINE_PERF_EVENT_MAP(network_events)
DEFINE_PERF_EVENT_MAP(cpu_sched_events)
DEFINE_PERF_EVENT_MAP(memory_events)
DEFINE_PERF_EVENT_MAP(file_io_events)
DEFINE_PERF_EVENT_MAP(lock_contention_events)
DEFINE_PERF_EVENT_MAP(interrupt_events)
DEFINE_PERF_EVENT_MAP(page_fault_events)
DEFINE_PERF_EVENT_MAP(security_events)
DEFINE_PERF_EVENT_MAP(container_events)

#undef DEFINE_PERF_EVENT_MAP
#endif

// 条件编译：事件存储Maps（仅在轮询模式下定义）
#ifdef OUTPUT_MODE_MAP_POLL
// 存储系统调用事件的映射 (用于syscall_event结构体)
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct syscall_event);
} syscall_events SEC(".maps");

// 存储进程生命周期事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct process_lifecycle_event);
} process_lifecycle_events SEC(".maps");

// 存储CPU调度信息
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct cpu_sched_info);
} cpu_sched_events SEC(".maps");

// 存储内存事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct memory_event);
} memory_events SEC(".maps");

// 存储文件IO事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct file_io_event);
} file_io_events SEC(".maps");

// 存储网络连接事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct network_connection);
} network_connection_events SEC(".maps");

// 存储网络流量统计
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u32);  // PID
    __type(value, struct network_traffic);
} network_traffic_stats SEC(".maps");

// 存储锁竞争事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct lock_contention_event);
} lock_contention_events SEC(".maps");

// 存储中断事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct interrupt_event);
} interrupt_events SEC(".maps");

// 存储页错误事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 8192);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct page_fault_event);
} page_fault_events SEC(".maps");

// 存储安全审计事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct security_event);
} security_events SEC(".maps");

// 存储容器事件
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 4096);
    __type(key, __u64);  // timestamp or unique ID
    __type(value, struct container_event);
} container_events SEC(".maps");
#endif

// 条件编译：输出函数宏定义
#ifdef OUTPUT_MODE_PERF_EVENT

// 定义perf_event输出函数的通用宏
#define DEFINE_PERF_OUTPUT_FUNC(func_name, map_name, event_type) \
static inline void func_name(struct event_type *event) { \
    bpf_perf_event_output((void *)bpf_get_current_task(), &map_name, \
                         BPF_F_CURRENT_CPU, event, sizeof(*event)); \
}

// 生成各类事件的输出函数
DEFINE_PERF_OUTPUT_FUNC(output_syscall_event, syscall_events, syscall_event)
DEFINE_PERF_OUTPUT_FUNC(output_process_event, process_events, process_lifecycle_event)
DEFINE_PERF_OUTPUT_FUNC(output_network_event, network_events, network_connection)
DEFINE_PERF_OUTPUT_FUNC(output_cpu_sched_event, cpu_sched_events, cpu_sched_info)
DEFINE_PERF_OUTPUT_FUNC(output_memory_event, memory_events, memory_event)
DEFINE_PERF_OUTPUT_FUNC(output_file_io_event, file_io_events, file_io_event)
DEFINE_PERF_OUTPUT_FUNC(output_lock_contention_event, lock_contention_events, lock_contention_event)
DEFINE_PERF_OUTPUT_FUNC(output_interrupt_event, interrupt_events, interrupt_event)
DEFINE_PERF_OUTPUT_FUNC(output_page_fault_event, page_fault_events, page_fault_event)
DEFINE_PERF_OUTPUT_FUNC(output_security_event, security_events, security_event)
DEFINE_PERF_OUTPUT_FUNC(output_container_event, container_events, container_event)

// 清理宏定义
#undef DEFINE_PERF_OUTPUT_FUNC

#endif


#ifdef OUTPUT_MODE_MAP_POLL

// 定义map存储函数的通用宏
#define DEFINE_MAP_STORE_FUNC(func_name, map_name, event_type) \
static inline void func_name(struct event_type *event) { \
    __u64 key = event->timestamp; \
    bpf_map_update_elem(&map_name, &key, event, BPF_ANY); \
}

// 生成各类事件的存储函数
DEFINE_MAP_STORE_FUNC(store_syscall_event, syscall_events, syscall_event)
DEFINE_MAP_STORE_FUNC(store_process_event, process_lifecycle_events, process_lifecycle_event)
DEFINE_MAP_STORE_FUNC(store_network_event, network_connection_events, network_connection)
DEFINE_MAP_STORE_FUNC(store_cpu_sched_event, cpu_sched_events, cpu_sched_info)
DEFINE_MAP_STORE_FUNC(store_memory_event, memory_events, memory_event)
DEFINE_MAP_STORE_FUNC(store_file_io_event, file_io_events, file_io_event)
DEFINE_MAP_STORE_FUNC(store_lock_contention_event, lock_contention_events, lock_contention_event)
DEFINE_MAP_STORE_FUNC(store_interrupt_event, interrupt_events, interrupt_event)
DEFINE_MAP_STORE_FUNC(store_page_fault_event, page_fault_events, page_fault_event)
DEFINE_MAP_STORE_FUNC(store_security_event, security_events, security_event)
DEFINE_MAP_STORE_FUNC(store_container_event, container_events, container_event)

// 清理宏定义
#undef DEFINE_MAP_STORE_FUNC

#endif

// 获取当前时间（纳秒）
static inline __u64 get_current_time(void) {
    return bpf_ktime_get_ns();
}

// 更新进程信息
static inline void update_process_info(__u32 pid, const char* syscall_name) {
    struct process_info *info;
    // 从 per-CPU 映射中获取结构体指针
    __u32 zero = 0;
    struct process_info *new_info = bpf_map_lookup_elem(&process_info_heap, &zero);
    if (!new_info) {
        return; // 如果获取失败则返回
    }

    info = bpf_map_lookup_elem(&process_map, &pid);
    if (!info) {
        // 初始化新进程信息
        new_info->pid = pid;
        new_info->syscall_count = 1;
        new_info->start_time = get_current_time();
        bpf_get_current_comm(&new_info->comm, sizeof(new_info->comm));
        bpf_map_update_elem(&process_map, &pid, new_info, BPF_ANY);
    } else {
        // 更新现有进程信息
        __sync_fetch_and_add(&info->syscall_count, 1);
        info->last_run_time = get_current_time();
    }
    
    // 同时更新系统调用计数
    __u64 *count = bpf_map_lookup_elem(&syscall_count, &pid);
    if (count) {
        (*count)++;
    } else {
        __u64 init_val = 1;
        bpf_map_update_elem(&syscall_count, &pid, &init_val, BPF_ANY);
    }

    bpf_printk("PID %d entering syscall: %s\n", pid, syscall_name);
}

// 通用系统调用处理函数
static inline int handle_syscall_enter(const char* syscall_name) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u32 tid = (__u32)pid_tgid;
    
    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;
    
    update_process_info(pid, syscall_name);
    return 0;
}


// 对应 syscall_event process_info security_event
// 对应 syscall_event process_info security_event
SEC("tp/syscalls/sys_enter_open")
int trace_open_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "open");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 创建安全审计事件 (security_event)
    // 只有在尝试访问敏感文件时才记录安全事件
    const char *filename = NULL;
    // 使用 bpf_core_read 获取参数，更安全的方式
    bpf_core_read(&filename, sizeof(filename), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[0]));
    
    if (filename) {
        // 检查是否为敏感文件路径
        char path_buffer[256];
        long filename_len = bpf_probe_read_str(path_buffer, sizeof(path_buffer), filename);
        
        if (filename_len > 0) {
            // 检查是否为敏感文件（可以根据需要扩展）
            if (filename_len >= 10 && 
                (bpf_strncmp(path_buffer, 10, "/etc/passwd") == 0 ||
                 bpf_strncmp(path_buffer, 9, "/etc/shadow") == 0 ||
                 bpf_strncmp(path_buffer, 11, "/proc/kcore") == 0 ||
                 bpf_strncmp(path_buffer, 9, "/etc/sudoers") == 0)) {
                
                struct security_event *sec_evt = bpf_map_lookup_elem(&security_event_heap, &zero);
                if (!sec_evt) {
                    return 0;
                }
                
                sec_evt->pid = pid;
                sec_evt->event_type = 0; // file_access
                sec_evt->timestamp = timestamp;
                bpf_get_current_comm(&sec_evt->comm, sizeof(sec_evt->comm));
                
                // 复制文件路径（限制长度）
                __u32 copy_len = filename_len < 255 ? filename_len : 255;
                bpf_probe_read(&sec_evt->path, copy_len, filename);
                sec_evt->path[copy_len] = '\0';
                
#ifdef OUTPUT_MODE_PERF_EVENT
                output_security_event(sec_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
                store_security_event(sec_evt);
#endif
            }
        }
    }

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_open")
int trace_open_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    __u32 syscall_nr = __NR_open; // open 系统调用号是固定的
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// TODO
// syscall_event process_info security_event
SEC("tp/syscalls/sys_enter_openat")
int trace_openat_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "openat");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 创建安全审计事件 (security_event)
    // 只有在尝试访问敏感文件时才记录安全事件
    const char *filename = NULL;
    // 使用 bpf_core_read 获取参数，更安全的方式
    bpf_core_read(&filename, sizeof(filename), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[1])); // openat的文件名是第二个参数
    
    if (filename) {
        // 检查是否为敏感文件路径
        char path_buffer[256];
        long filename_len = bpf_probe_read_str(path_buffer, sizeof(path_buffer), filename);
        
        if (filename_len > 0) {
            // 检查是否为敏感文件（可以根据需要扩展）
            if (filename_len >= 10 && 
                (bpf_strncmp(path_buffer, 10, "/etc/passwd") == 0 ||
                 bpf_strncmp(path_buffer, 9, "/etc/shadow") == 0 ||
                 bpf_strncmp(path_buffer, 11, "/proc/kcore") == 0 ||
                 bpf_strncmp(path_buffer, 9, "/etc/sudoers") == 0)) {
                
                struct security_event *sec_evt = bpf_map_lookup_elem(&security_event_heap, &zero);
                if (!sec_evt) {
                    return 0;
                }
                
                sec_evt->pid = pid;
                sec_evt->event_type = 0; // file_access
                sec_evt->timestamp = timestamp;
                bpf_get_current_comm(&sec_evt->comm, sizeof(sec_evt->comm));
                
                // 复制文件路径（限制长度）
                __u32 copy_len = filename_len < 255 ? filename_len : 255;
                bpf_probe_read(&sec_evt->path, copy_len, filename);
                sec_evt->path[copy_len] = '\0';
                
#ifdef OUTPUT_MODE_PERF_EVENT
                output_security_event(sec_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
                store_security_event(sec_evt);
#endif
            }
        }
    }

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_openat")
int trace_openat_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，openat 系统调用在大多数架构上是 257
    __u32 syscall_nr = 257; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// file_io_event syscall_event process_info
SEC("tp/syscalls/sys_enter_read")
int trace_read_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "read");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 创建文件IO事件 (file_io_event)
    struct file_io_event *io_evt = bpf_map_lookup_elem(&file_io_events, &zero);
    if (!io_evt) {
        return 0;
    }

    // 从 ctx 中读取参数
    __u64 fd, count;
    bpf_core_read(&fd, sizeof(fd), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[0])); // read的第一个参数是fd
    bpf_core_read(&count, sizeof(count), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[2])); // read的第三个参数是count

    io_evt->pid = pid;
    io_evt->fd = fd;
    io_evt->bytes = count; // 预期读取的字节数
    io_evt->timestamp = timestamp;
    io_evt->operation = 0; // 0表示read操作
    io_evt->latency = 0; // 在exit时计算
    bpf_get_current_comm(&io_evt->comm, sizeof(io_evt->comm));
    // 文件名无法在enter事件中获取，留空
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_file_io_event(io_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_file_io_event(io_evt);
#endif

    return 0;
}

// syscall_event process_info file_io_event
SEC("tp/syscalls/sys_exit_read")
int trace_read_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，read 系统调用在大多数架构上是 0
    __u32 syscall_nr = 0; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 更新文件IO事件 (file_io_event)
    // 只有在读取成功时才记录IO事件
    if ((__s64)ret >= 0) { // read系统调用返回负数表示错误
        struct file_io_event *io_evt = bpf_map_lookup_elem(&file_io_events, &zero);
        if (!io_evt) {
            return 0;
        }

        io_evt->pid = pid;
        // fd参数无法直接从exit事件中获取，但我们可以保留enter事件中设置的值
        io_evt->bytes = ret; // 实际读取的字节数
        io_evt->timestamp = timestamp;
        io_evt->operation = 0; // 0表示read操作
        io_evt->latency = syscall_evt->duration; // 使用系统调用的持续时间作为IO延迟
        bpf_get_current_comm(&io_evt->comm, sizeof(io_evt->comm));
        // 文件名无法在exit事件中获取，留空
        
#ifdef OUTPUT_MODE_PERF_EVENT
        output_file_io_event(io_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
        store_file_io_event(io_evt);
#endif
    }

    return 0;
}


// syscall_event process_info file_io_event
SEC("tp/syscalls/sys_enter_write")
int trace_write_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "write");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 创建文件IO事件 (file_io_event)
    struct file_io_event *io_evt = bpf_map_lookup_elem(&file_io_events, &zero);
    if (!io_evt) {
        return 0;
    }

    // 从 ctx 中读取参数
    __u64 fd, count;
    bpf_core_read(&fd, sizeof(fd), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[0])); // write的第一个参数是fd
    bpf_core_read(&count, sizeof(count), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[2])); // write的第三个参数是count

    io_evt->pid = pid;
    io_evt->fd = fd;
    io_evt->bytes = count; // 预期写入的字节数
    io_evt->timestamp = timestamp;
    io_evt->operation = 1; // 1表示write操作
    io_evt->latency = 0; // 在exit时计算
    bpf_get_current_comm(&io_evt->comm, sizeof(io_evt->comm));
    // 文件名无法在enter事件中获取，留空
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_file_io_event(io_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_file_io_event(io_evt);
#endif

    return 0;
}

// syscall_event process_info file_io_event
SEC("tp/syscalls/sys_exit_write")
int trace_write_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，write 系统调用在大多数架构上是 1
    __u32 syscall_nr = 1; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 更新文件IO事件 (file_io_event)
    // 只有在写入成功时才记录IO事件
    if ((__s64)ret >= 0) { // write系统调用返回负数表示错误
        struct file_io_event *io_evt = bpf_map_lookup_elem(&file_io_events, &zero);
        if (!io_evt) {
            return 0;
        }

        io_evt->pid = pid;
        // fd参数无法直接从exit事件中获取，但我们可以保留enter事件中设置的值
        io_evt->bytes = ret; // 实际写入的字节数
        io_evt->timestamp = timestamp;
        io_evt->operation = 1; // 1表示write操作
        io_evt->latency = syscall_evt->duration; // 使用系统调用的持续时间作为IO延迟
        bpf_get_current_comm(&io_evt->comm, sizeof(io_evt->comm));
        // 文件名无法在exit事件中获取，留空
        
#ifdef OUTPUT_MODE_PERF_EVENT
        output_file_io_event(io_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
        store_file_io_event(io_evt);
#endif
    }

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_enter_connect")
int trace_connect_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "connect");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_connect")
int trace_connect_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，connect 系统调用在大多数架构上是 42
    __u32 syscall_nr = 42; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_enter_clone")
int trace_clone_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "clone");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_clone")
int trace_clone_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，clone 系统调用在大多数架构上是 56
    __u32 syscall_nr = 56; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_enter_mmap")
int trace_mmap_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "mmap");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_mmap")
int trace_mmap_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，mmap 系统调用在大多数架构上是 9
    __u32 syscall_nr = 9; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_enter_socket")     // socket进入
int trace_socket_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "socket");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_socket")     // socket退出
int trace_socket_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，socket 系统调用在大多数架构上是 41
    __u32 syscall_nr = 41; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}

// syscall_event process_info security_event
SEC("tp/syscalls/sys_enter_execve")     // 创建进程
int trace_execve_enter(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 syscall_nr;
    bpf_core_read(&syscall_nr, sizeof(syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    
    // 使用PID和系统调用号组合作为键
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

    // 1. 更新进程信息 (process_info)
    update_process_info(pid, "execve");

    // 2. 创建系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }
    
    syscall_evt->pid = pid;
    // 使用 bpf_core_read 获取系统调用号，更安全的方式
    bpf_core_read(&syscall_evt->syscall_nr, sizeof(syscall_evt->syscall_nr), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, id));
    syscall_evt->timestamp = timestamp;
    syscall_evt->duration = 0;  // 在exit时计算
    syscall_evt->retval = 0;    // 在exit时设置
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    // 3. 创建安全审计事件 (security_event)
    // 只有在尝试执行程序时才记录安全事件
    const char *filename = NULL;
    // 使用 bpf_core_read 获取参数，更安全的方式
    bpf_core_read(&filename, sizeof(filename), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_enter, args[0])); // execve的第一个参数是文件路径
    
    if (filename) {
        // 检查是否为敏感文件路径
        char path_buffer[256];
        long filename_len = bpf_probe_read_str(path_buffer, sizeof(path_buffer), filename);
        
        if (filename_len > 0) {
            // 检查是否为敏感文件（可以根据需要扩展）
            // 例如，检查是否在敏感目录中执行程序
            if (filename_len >= 5 && 
                (bpf_strncmp(path_buffer, 5, "/tmp/") == 0 ||
                 bpf_strncmp(path_buffer, 9, "/var/tmp/") == 0 ||
                 bpf_strncmp(path_buffer, 4, "/dev/") == 0)) {
                
                struct security_event *sec_evt = bpf_map_lookup_elem(&security_event_heap, &zero);
                if (!sec_evt) {
                    return 0;
                }
                
                sec_evt->pid = pid;
                sec_evt->event_type = 2; // program_execution (假设2表示程序执行)
                sec_evt->timestamp = timestamp;
                bpf_get_current_comm(&sec_evt->comm, sizeof(sec_evt->comm));
                
                // 复制文件路径（限制长度）
                __u32 copy_len = filename_len < 255 ? filename_len : 255;
                bpf_probe_read(&sec_evt->path, copy_len, filename);
                sec_evt->path[copy_len] = '\0';
                
#ifdef OUTPUT_MODE_PERF_EVENT
                output_security_event(sec_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
                store_security_event(sec_evt);
#endif
            }
        }
    }

    return 0;
}

// syscall_event process_info
SEC("tp/syscalls/sys_exit_execve")     // 创建退出
int trace_execve_exit(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 1. 更新进程信息 (process_info)
    struct process_info *info = bpf_map_lookup_elem(&process_map, &pid);
    if (info) {
        // 更新进程的最后运行时间
        info->last_run_time = timestamp;
    }

    // 2. 更新系统调用事件 (syscall_event)
    __u32 zero = 0;
    struct syscall_event *syscall_evt = bpf_map_lookup_elem(&syscall_event_heap, &zero);
    if (!syscall_evt) {
        return 0;
    }

    // 从 ctx 中读取系统调用返回值
    __u64 ret;
    bpf_core_read(&ret, sizeof(ret), 
                  (void *)ctx + offsetof(struct trace_event_raw_sys_exit, ret));

    // 填充 syscall_event 结构体
    syscall_evt->pid = pid;
    // 使用硬编码的系统调用号，execve 系统调用在大多数架构上是 59
    __u32 syscall_nr = 59; 
    syscall_evt->syscall_nr = syscall_nr;
    syscall_evt->timestamp = timestamp;
    syscall_evt->retval = ret;
    bpf_get_current_comm(&syscall_evt->comm, sizeof(syscall_evt->comm));
    
    // 计算系统调用持续时间
    __u64 enter_key = ((__u64)pid << 32) | syscall_nr;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        syscall_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        syscall_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_syscall_event(syscall_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_syscall_event(syscall_evt);
#endif

    return 0;
}


// 对应 struct process_lifecycle_event
SEC("tp/sched/sched_process_fork")     // 进程创建
int trace_process_fork(void *ctx) {
    __u64 timestamp = get_current_time();
    
    // 从 ctx 中读取参数
    __u32 child_pid, parent_pid;
    char child_comm[16];
    
    bpf_core_read(&child_pid, sizeof(child_pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_process_fork, child_pid));
    bpf_core_read(&parent_pid, sizeof(parent_pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_process_fork, parent_pid));
    bpf_core_read_str(&child_comm, sizeof(child_comm), 
                      (void *)ctx + offsetof(struct trace_event_raw_sched_process_fork, child_comm));
    
    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && parent_pid != my_pid && child_pid != my_pid)
        return 0;
    
    // 创建进程生命周期事件 (process_lifecycle_event)
    __u32 zero = 0;
    struct process_lifecycle_event *process_evt = bpf_map_lookup_elem(&process_lifecycle_event_heap, &zero);
    if (!process_evt) {
        return 0;
    }
    
    process_evt->pid = child_pid;
    process_evt->ppid = parent_pid;
    process_evt->event_type = 0; // 0表示创建事件
    process_evt->timestamp = timestamp;
    bpf_probe_read_str(&process_evt->comm, sizeof(process_evt->comm), child_comm);
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_process_event(process_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_process_event(process_evt);
#endif

    return 0;
}

SEC("tp/sched/sched_process_exit")     // 进程退出
int trace_process_exit(void *ctx) {
    __u64 timestamp = get_current_time();
    
    // 从 ctx 中读取参数
    __u32 pid;
    char comm[16];
    
    bpf_core_read(&pid, sizeof(pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_process_template, pid));
    bpf_core_read_str(&comm, sizeof(comm), 
                      (void *)ctx + offsetof(struct trace_event_raw_sched_process_template, comm));
    
    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;
    
    // 创建进程生命周期事件 (process_lifecycle_event)
    __u32 zero = 0;
    struct process_lifecycle_event *process_evt = bpf_map_lookup_elem(&process_lifecycle_event_heap, &zero);
    if (!process_evt) {
        return 0;
    }
    
    process_evt->pid = pid;
    process_evt->ppid = 0; // 进程退出时无法获取父进程ID
    process_evt->event_type = 1; // 1表示退出事件
    process_evt->timestamp = timestamp;
    bpf_probe_read_str(&process_evt->comm, sizeof(process_evt->comm), comm);
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_process_event(process_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_process_event(process_evt);
#endif

    return 0;
}


// 对应 struct cpu_sched_info
SEC("tp/sched/sched_switch")           // 进程切换
int trace_cpu_sched_switch(void *ctx) {
    __u64 timestamp = get_current_time();
    
    // 从 ctx 中读取参数
    char prev_comm[16], next_comm[16];
    __u32 prev_pid, next_pid;
    __u32 cpu = bpf_get_smp_processor_id();
    
    bpf_core_read_str(&prev_comm, sizeof(prev_comm), 
                      (void *)ctx + offsetof(struct trace_event_raw_sched_switch, prev_comm));
    bpf_core_read(&prev_pid, sizeof(prev_pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_switch, prev_pid));
    
    bpf_core_read_str(&next_comm, sizeof(next_comm), 
                      (void *)ctx + offsetof(struct trace_event_raw_sched_switch, next_comm));
    bpf_core_read(&next_pid, sizeof(next_pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_switch, next_pid));
    
    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && prev_pid != my_pid && next_pid != my_pid)
        return 0;
    
    // 创建CPU调度事件
    __u32 zero = 0;
    struct cpu_sched_info *sched_evt = bpf_map_lookup_elem(&cpu_sched_events, &zero);
    if (!sched_evt) {
        return 0;
    }
    
    // 记录被调度出去的进程信息
    sched_evt->pid = prev_pid;
    sched_evt->cpu = cpu;
    sched_evt->timestamp = timestamp;
    sched_evt->wait_time = 0; // 简化处理，实际应该计算等待时间
    sched_evt->run_time = 0;  // 简化处理，实际应该计算运行时间
    bpf_probe_read_str(&sched_evt->comm, sizeof(sched_evt->comm), prev_comm);
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_cpu_sched_event(sched_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_cpu_sched_event(sched_evt);
#endif

    return 0;
}

SEC("tp/sched/sched_wakeup")           // 进程唤醒
int trace_sched_wakeup(void *ctx) {
    __u64 timestamp = get_current_time();
    
    // 从 ctx 中读取参数
    char comm[16];
    __u32 pid;
    __u32 target_cpu;
    
    bpf_core_read_str(&comm, sizeof(comm), 
                      (void *)ctx + offsetof(struct trace_event_raw_sched_wakeup_template, comm));
    bpf_core_read(&pid, sizeof(pid), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_wakeup_template, pid));
    bpf_core_read(&target_cpu, sizeof(target_cpu), 
                  (void *)ctx + offsetof(struct trace_event_raw_sched_wakeup_template, target_cpu));
    
    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;
    
    // 创建CPU调度事件
    __u32 zero = 0;
    struct cpu_sched_info *sched_evt = bpf_map_lookup_elem(&cpu_sched_events, &zero);
    if (!sched_evt) {
        return 0;
    }
    
    sched_evt->pid = pid;
    sched_evt->cpu = target_cpu;
    sched_evt->timestamp = timestamp;
    sched_evt->wait_time = 0; // 简化处理，实际应该计算等待时间
    sched_evt->run_time = 0;  // 简化处理，实际应该计算运行时间
    bpf_probe_read_str(&sched_evt->comm, sizeof(sched_evt->comm), comm);
    
#ifdef OUTPUT_MODE_PERF_EVENT
    output_cpu_sched_event(sched_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_cpu_sched_event(sched_evt);
#endif

    return 0;
}


// 对应 struct memory_event
SEC("kprobe/__kmalloc")                  // 内核内存分配
int trace_kmalloc(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 从寄存器中获取参数
    size_t size = PT_REGS_PARM2(ctx);  // kmalloc的size参数在第二个寄存器中

    // 创建内存事件
    __u32 zero = 0;
    struct memory_event *mem_evt = bpf_map_lookup_elem(&memory_events, &zero);
    if (!mem_evt) {
        return 0;
    }

    mem_evt->pid = pid;
    mem_evt->event_type = 0; // 0表示kmalloc
    mem_evt->size = size;
    mem_evt->timestamp = timestamp;
    mem_evt->addr = 0; // 地址在进入时无法获取
    bpf_get_current_comm(&mem_evt->comm, sizeof(mem_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_memory_event(mem_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_memory_event(mem_evt);
#endif

    return 0;
}

SEC("kprobe/__x64_sys_mmap")                     // 用户态内存映射
int trace_mmap(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 从寄存器中获取参数
    size_t length = PT_REGS_PARM2(ctx);  // mmap的length参数在第二个寄存器中

    // 创建内存事件
    __u32 zero = 0;
    struct memory_event *mem_evt = bpf_map_lookup_elem(&memory_events, &zero);
    if (!mem_evt) {
        return 0;
    }

    mem_evt->pid = pid;
    mem_evt->event_type = 1; // 1表示mmap
    mem_evt->size = length;
    mem_evt->timestamp = timestamp;
    mem_evt->addr = 0; // 地址在进入时无法获取
    bpf_get_current_comm(&mem_evt->comm, sizeof(mem_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_memory_event(mem_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_memory_event(mem_evt);
#endif

    return 0;
}

SEC("kprobe/kmem_cache_alloc")               // slab分配器
int trace_slab_alloc(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 从寄存器中获取参数
    size_t size = PT_REGS_PARM2(ctx);  // slab_alloc的size参数在第二个寄存器中

    // 创建内存事件
    __u32 zero = 0;
    struct memory_event *mem_evt = bpf_map_lookup_elem(&memory_events, &zero);
    if (!mem_evt) {
        return 0;
    }

    mem_evt->pid = pid;
    mem_evt->event_type = 2; // 2表示slab_alloc
    mem_evt->size = size;
    mem_evt->timestamp = timestamp;
    mem_evt->addr = 0; // 地址在进入时无法获取
    bpf_get_current_comm(&mem_evt->comm, sizeof(mem_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_memory_event(mem_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_memory_event(mem_evt);
#endif

    return 0;
}

SEC("kprobe/__x64_sys_brk")                      // 堆内存扩展
int trace_brk(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 从寄存器中获取参数
    void *addr = (void *)PT_REGS_PARM1(ctx);  // brk的addr参数在第一个寄存器中

    // 创建内存事件
    __u32 zero = 0;
    struct memory_event *mem_evt = bpf_map_lookup_elem(&memory_events, &zero);
    if (!mem_evt) {
        return 0;
    }

    mem_evt->pid = pid;
    mem_evt->event_type = 3; // 3表示brk
    mem_evt->size = 0; // brk不直接传递大小
    mem_evt->timestamp = timestamp;
    mem_evt->addr = (unsigned long)addr;
    bpf_get_current_comm(&mem_evt->comm, sizeof(mem_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_memory_event(mem_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_memory_event(mem_evt);
#endif

    return 0;
}


// 对应 struct file_io_event
// SEC("tp/syscalls/sys_enter_read")
// int trace_read_enter(struct trace_event_raw_sys_enter *ctx) { return 0; }
// SEC("tp/syscalls/sys_exit_read")
// int trace_read_exit(struct trace_event_raw_sys_exit *ctx) { return 0; }
// SEC("tp/syscalls/sys_enter_write")
// int trace_write_enter(struct trace_event_raw_sys_enter *ctx) { return 0; }
// SEC("tp/syscalls/sys_exit_write")
// int trace_write_exit(struct trace_event_raw_sys_exit *ctx) { return 0; }
// 或者使用vfs层监控
// SEC("kprobe/vfs_read")      // 读文件
// int trace_vfs_read(struct pt_regs *ctx) { return 0; }

// SEC("kprobe/vfs_write")      // 写文件
// int trace_vfs_write(struct pt_regs *ctx) { return 0; }


// 对应 struct network_connection 和 struct network_traffic
SEC("kprobe/tcp_v4_connect")           // TCP连接建立
int trace_tcp_v4_connect(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 获取sock参数
    struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
    if (!sk)
        return 0;

    // 读取源和目标地址信息
    __u32 saddr, daddr;
    __u16 sport, dport;
    
    bpf_probe_read_kernel(&saddr, sizeof(saddr), &sk->__sk_common.skc_rcv_saddr);
    bpf_probe_read_kernel(&daddr, sizeof(daddr), &sk->__sk_common.skc_daddr);
    bpf_probe_read_kernel(&sport, sizeof(sport), &sk->__sk_common.skc_num);
    // dport存储在inet_dport中
    bpf_probe_read_kernel(&dport, sizeof(dport), &sk->__sk_common.skc_dport);
    // 网络字节序转换
    dport = __bpf_ntohs(dport);

    // 创建网络连接事件 (处理network_connection结构体)
    __u32 zero = 0;
    struct network_connection *net_evt = bpf_map_lookup_elem(&network_connection_event_heap, &zero);
    if (!net_evt) {
        return 0;
    }

    net_evt->pid = pid;
    net_evt->saddr = saddr;
    net_evt->daddr = daddr;
    net_evt->sport = sport;
    net_evt->dport = dport;
    net_evt->protocol = 6; // TCP协议
    net_evt->event_type = 0; // 0表示连接建立
    net_evt->timestamp = timestamp;
    bpf_get_current_comm(&net_evt->comm, sizeof(net_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_network_event(net_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_network_event(net_evt);
#endif

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (!traffic) {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}

SEC("kprobe/tcp_close")                // TCP连接关闭
int trace_tcp_close(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 获取sock参数
    struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
    if (!sk)
        return 0;

    // 读取源和目标地址信息
    __u32 saddr, daddr;
    __u16 sport, dport;
    
    bpf_probe_read_kernel(&saddr, sizeof(saddr), &sk->__sk_common.skc_rcv_saddr);
    bpf_probe_read_kernel(&daddr, sizeof(daddr), &sk->__sk_common.skc_daddr);
    bpf_probe_read_kernel(&sport, sizeof(sport), &sk->__sk_common.skc_num);
    // dport存储在inet_dport中
    bpf_probe_read_kernel(&dport, sizeof(dport), &sk->__sk_common.skc_dport);
    // 网络字节序转换
    dport = __bpf_ntohs(dport);

    // 创建网络连接事件 (处理network_connection结构体)
    __u32 zero = 0;
    struct network_connection *net_evt = bpf_map_lookup_elem(&network_connection_event_heap, &zero);
    if (!net_evt) {
        return 0;
    }

    net_evt->pid = pid;
    net_evt->saddr = saddr;
    net_evt->daddr = daddr;
    net_evt->sport = sport;
    net_evt->dport = dport;
    net_evt->protocol = 6; // TCP协议
    net_evt->event_type = 1; // 1表示连接关闭
    net_evt->timestamp = timestamp;
    bpf_get_current_comm(&net_evt->comm, sizeof(net_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_network_event(net_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_network_event(net_evt);
#endif

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (traffic) {
        // 更新时间戳
        traffic->timestamp = timestamp;
    } else {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}

SEC("kprobe/tcp_set_state")            // TCP状态改变
int trace_tcp_set_state(struct pt_regs *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 获取sock参数和状态参数
    struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
    if (!sk)
        return 0;

    // 读取源和目标地址信息
    __u32 saddr, daddr;
    __u16 sport, dport;
    
    bpf_probe_read_kernel(&saddr, sizeof(saddr), &sk->__sk_common.skc_rcv_saddr);
    bpf_probe_read_kernel(&daddr, sizeof(daddr), &sk->__sk_common.skc_daddr);
    bpf_probe_read_kernel(&sport, sizeof(sport), &sk->__sk_common.skc_num);
    // dport存储在inet_dport中
    bpf_probe_read_kernel(&dport, sizeof(dport), &sk->__sk_common.skc_dport);
    // 网络字节序转换
    dport = __bpf_ntohs(dport);

    // 创建网络连接事件 (处理network_connection结构体)
    __u32 zero = 0;
    struct network_connection *net_evt = bpf_map_lookup_elem(&network_connection_event_heap, &zero);
    if (!net_evt) {
        return 0;
    }

    net_evt->pid = pid;
    net_evt->saddr = saddr;
    net_evt->daddr = daddr;
    net_evt->sport = sport;
    net_evt->dport = dport;
    net_evt->protocol = 6; // TCP协议
    net_evt->event_type = 2; // 2表示状态改变
    net_evt->timestamp = timestamp;
    bpf_get_current_comm(&net_evt->comm, sizeof(net_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_network_event(net_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_network_event(net_evt);
#endif

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (traffic) {
        // 更新时间戳
        traffic->timestamp = timestamp;
    } else {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}

SEC("kprobe/udp_sendmsg")              // UDP发送
int trace_udp_sendmsg(void *ctx) {
    // 参数使用void *是因为在该监控点上，我们不需要从寄存器中提取特定参数
    // 我们只关注进程ID和更新流量统计
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (traffic) {
        // 增加发送字节数（由于参数获取复杂，这里简化处理）
        __sync_fetch_and_add(&traffic->bytes_sent, 512); // 示例值
        traffic->timestamp = timestamp;
    } else {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.bytes_sent = 512; // 示例值
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}

SEC("kprobe/tcp_sendmsg")              // TCP发送
int trace_tcp_sendmsg(void *ctx) {
    // 参数使用void *是因为在该监控点上，我们不需要从寄存器中提取特定参数
    // 我们只关注进程ID和更新流量统计
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (traffic) {
        // 增加发送字节数（由于参数获取复杂，这里简化处理）
        __sync_fetch_and_add(&traffic->bytes_sent, 1024); // 示例值
        traffic->timestamp = timestamp;
    } else {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.bytes_sent = 1024; // 示例值
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}

SEC("kprobe/tcp_rcv_established")      // TCP接收数据
int trace_tcp_rcv_established(void *ctx) {
    // 参数使用void *是因为在该监控点上，我们不需要从寄存器中提取特定参数
    // 我们只关注进程ID和更新流量统计
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 更新网络流量统计 (处理network_traffic结构体)
    struct network_traffic *traffic = bpf_map_lookup_elem(&network_traffic_stat_heap, &pid);
    if (traffic) {
        // 增加接收字节数（由于参数获取复杂，这里简化处理）
        __sync_fetch_and_add(&traffic->bytes_received, 1024); // 示例值
        traffic->timestamp = timestamp;
    } else {
        // 初始化新的流量统计记录
        struct network_traffic new_traffic = {};
        new_traffic.pid = pid;
        new_traffic.bytes_received = 1024; // 示例值
        new_traffic.timestamp = timestamp;
        bpf_get_current_comm(&new_traffic.comm, sizeof(new_traffic.comm));
        bpf_map_update_elem(&network_traffic_stat_heap, &pid, &new_traffic, BPF_ANY);
    }

    return 0;
}


// 对应 struct lock_contention_event
SEC("kprobe/mutex_lock")               // 互斥锁获取
int trace_mutex_lock(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 创建锁竞争事件
    __u32 zero = 0;
    struct lock_contention_event *lock_evt = bpf_map_lookup_elem(&lock_contention_event_heap, &zero);
    if (!lock_evt) {
        return 0;
    }

    lock_evt->pid = pid;
    lock_evt->lock_type = 0; // mutex
    lock_evt->wait_time = 0; // kprobe时无法计算等待时间，需要结合kretprobe
    lock_evt->timestamp = timestamp;
    bpf_get_current_comm(&lock_evt->comm, sizeof(lock_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_lock_contention_event(lock_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_lock_contention_event(lock_evt);
#endif

    return 0;
}

SEC("kprobe/mutex_unlock")             // 互斥锁释放
int trace_mutex_unlock(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 创建锁竞争事件
    __u32 zero = 0;
    struct lock_contention_event *lock_evt = bpf_map_lookup_elem(&lock_contention_event_heap, &zero);
    if (!lock_evt) {
        return 0;
    }

    lock_evt->pid = pid;
    lock_evt->lock_type = 0; // mutex
    lock_evt->wait_time = 0; // 释放时也不计算等待时间
    lock_evt->timestamp = timestamp;
    bpf_get_current_comm(&lock_evt->comm, sizeof(lock_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_lock_contention_event(lock_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_lock_contention_event(lock_evt);
#endif

    return 0;
}

SEC("kprobe/_raw_spin_lock")           // 自旋锁获取
int trace_spin_lock(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 创建锁竞争事件
    __u32 zero = 0;
    struct lock_contention_event *lock_evt = bpf_map_lookup_elem(&lock_contention_event_heap, &zero);
    if (!lock_evt) {
        return 0;
    }

    lock_evt->pid = pid;
    lock_evt->lock_type = 1; // spinlock
    lock_evt->wait_time = 0; // kprobe时无法计算等待时间
    lock_evt->timestamp = timestamp;
    bpf_get_current_comm(&lock_evt->comm, sizeof(lock_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_lock_contention_event(lock_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_lock_contention_event(lock_evt);
#endif

    return 0;
}

SEC("kprobe/_raw_spin_unlock")         // 自旋锁释放
int trace_spin_unlock(void *ctx) {
    __u64 pid_tgid = bpf_get_current_pid_tgid();
    __u32 pid = pid_tgid >> 32;
    __u64 timestamp = get_current_time();

    // 如果指定了特定PID，则只监控该PID
    if (my_pid != 0 && pid != my_pid)
        return 0;

    // 创建锁竞争事件
    __u32 zero = 0;
    struct lock_contention_event *lock_evt = bpf_map_lookup_elem(&lock_contention_event_heap, &zero);
    if (!lock_evt) {
        return 0;
    }

    lock_evt->pid = pid;
    lock_evt->lock_type = 1; // spinlock
    lock_evt->wait_time = 0; // 释放时也不计算等待时间
    lock_evt->timestamp = timestamp;
    bpf_get_current_comm(&lock_evt->comm, sizeof(lock_evt->comm));

#ifdef OUTPUT_MODE_PERF_EVENT
    output_lock_contention_event(lock_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_lock_contention_event(lock_evt);
#endif

    return 0;
}


// 对应 struct interrupt_event
SEC("tp/irq/irq_handler_entry")        // 硬件中断入口
int trace_irq_handler_entry(void *ctx) {
    __u64 timestamp = get_current_time();
    __u32 cpu = bpf_get_smp_processor_id();

    // 从上下文中读取中断号
    __u32 irq_num = 0;
    bpf_core_read(&irq_num, sizeof(irq_num), 
                  (void *)ctx + offsetof(struct trace_event_raw_irq_handler_entry, irq));

    // 创建中断事件
    __u32 zero = 0;
    struct interrupt_event *intr_evt = bpf_map_lookup_elem(&interrupt_event_heap, &zero);
    if (!intr_evt) {
        return 0;
    }

    intr_evt->irq_num = irq_num;
    intr_evt->cpu = cpu;
    intr_evt->event_type = 0; // hard interrupt
    intr_evt->duration = 0; // 在入口处无法知道处理耗时
    intr_evt->timestamp = timestamp;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 enter_key = ((__u64)cpu << 32) | irq_num;
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

#ifdef OUTPUT_MODE_PERF_EVENT
    output_interrupt_event(intr_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_interrupt_event(intr_evt);
#endif

    return 0;
}

SEC("tp/irq/irq_handler_exit")         // 硬件中断出口
int trace_irq_handler_exit(void *ctx) {
    __u64 timestamp = get_current_time();
    __u32 cpu = bpf_get_smp_processor_id();

    // 从上下文中读取中断号
    __u32 irq_num = 0;
    bpf_core_read(&irq_num, sizeof(irq_num), 
                  (void *)ctx + offsetof(struct trace_event_raw_irq_handler_exit, irq));

    // 创建中断事件
    __u32 zero = 0;
    struct interrupt_event *intr_evt = bpf_map_lookup_elem(&interrupt_event_heap, &zero);
    if (!intr_evt) {
        return 0;
    }

    intr_evt->irq_num = irq_num;
    intr_evt->cpu = cpu;
    intr_evt->event_type = 0; // hard interrupt
    intr_evt->timestamp = timestamp;

    // 计算中断处理耗时
    __u64 enter_key = ((__u64)cpu << 32) | irq_num;
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        intr_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        intr_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_interrupt_event(intr_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_interrupt_event(intr_evt);
#endif

    return 0;
}

SEC("kprobe/__do_softirq")        // 软中断入口
int trace_softirq_entry(void *ctx) {
    __u64 timestamp = get_current_time();
    __u32 cpu = bpf_get_smp_processor_id();

    // 从上下文中读取软中断向量号
    __u32 vec = 0;
    bpf_core_read(&vec, sizeof(vec), 
                  (void *)ctx + offsetof(struct trace_event_raw_softirq, vec));

    // 创建中断事件
    __u32 zero = 0;
    struct interrupt_event *intr_evt = bpf_map_lookup_elem(&interrupt_event_heap, &zero);
    if (!intr_evt) {
        return 0;
    }

    intr_evt->irq_num = vec;
    intr_evt->cpu = cpu;
    intr_evt->event_type = 1; // soft interrupt
    intr_evt->duration = 0; // 在入口处无法知道处理耗时
    intr_evt->timestamp = timestamp;

    // 存储进入时间戳，用于在退出时计算持续时间
    __u64 enter_key = (((__u64)cpu << 32) | ((__u64)1 << 32)) | vec; // 使用高位标记软中断
    bpf_map_update_elem(&syscall_enter_time, &enter_key, &timestamp, BPF_ANY);

#ifdef OUTPUT_MODE_PERF_EVENT
    output_interrupt_event(intr_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_interrupt_event(intr_evt);
#endif

    return 0;
}

SEC("kprobe/irq_exit")         // 软中断出口
int trace_softirq_exit(void *ctx) {
    __u64 timestamp = get_current_time();
    __u32 cpu = bpf_get_smp_processor_id();

    // 从上下文中读取软中断向量号
    __u32 vec = 0;
    bpf_core_read(&vec, sizeof(vec), 
                  (void *)ctx + offsetof(struct trace_event_raw_softirq, vec));

    // 创建中断事件
    __u32 zero = 0;
    struct interrupt_event *intr_evt = bpf_map_lookup_elem(&interrupt_event_heap, &zero);
    if (!intr_evt) {
        return 0;
    }

    intr_evt->irq_num = vec;
    intr_evt->cpu = cpu;
    intr_evt->event_type = 1; // soft interrupt
    intr_evt->timestamp = timestamp;

    // 计算软中断处理耗时
    __u64 enter_key = (((__u64)cpu << 32) | ((__u64)1 << 32)) | vec; // 使用高位标记软中断
    __u64 *enter_time = bpf_map_lookup_elem(&syscall_enter_time, &enter_key);
    if (enter_time) {
        intr_evt->duration = timestamp - *enter_time;
        // 删除已处理的进入时间戳，避免映射无限增长
        bpf_map_delete_elem(&syscall_enter_time, &enter_key);
    } else {
        intr_evt->duration = 0;
    }

#ifdef OUTPUT_MODE_PERF_EVENT
    output_interrupt_event(intr_evt);
#elif defined(OUTPUT_MODE_MAP_POLL)
    store_interrupt_event(intr_evt);
#endif

    return 0;
}



// SEC("tp/syscalls/sys_enter_open")      // 文件访问
// int trace_open_enter(struct trace_event_raw_sys_enter *ctx) { return 0; }
// SEC("tp/syscalls/sys_enter_openat")
// int trace_openat_enter(struct trace_event_raw_sys_enter *ctx) { return 0; }
// SEC("tp/syscalls/sys_enter_execve")    // 程序执行
// int trace_execve_enter(struct trace_event_raw_sys_enter *ctx) { return 0; }
// 对应 struct security_event
SEC("tp/syscalls/sys_enter_setuid")    // 权限变更
int trace_setuid_enter(struct trace_event_raw_sys_enter *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u32 zero = 0;
    struct security_event *event = bpf_map_lookup_elem(&security_event_heap, &zero);
    if (!event)
        return 0;
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->event_type = 1; // 权限变更类型
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#endif
    
    return 0;
}

SEC("tp/syscalls/sys_enter_capset")    // 能力变更
int trace_capset_enter(struct trace_event_raw_sys_enter *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u32 zero = 0;
    struct security_event *event = bpf_map_lookup_elem(&security_event_heap, &zero);
    if (!event)
        return 0;
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->event_type = 1; // 权限变更类型（能力变更也属于权限变更）
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#endif
    
    return 0;
}

SEC("kprobe/security_inode_create")    // 文件创建
int trace_inode_create(struct pt_regs *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u32 zero = 0;
    struct security_event *event = bpf_map_lookup_elem(&security_event_heap, &zero);
    if (!event)
        return 0;
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->event_type = 0; // 文件访问类型
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#endif
    
    return 0;
}

SEC("kprobe/security_file_open") // 文件打开
int trace_file_open(struct pt_regs *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u32 zero = 0;
    struct security_event *event = bpf_map_lookup_elem(&security_event_heap, &zero);
    if (!event)
        return 0;
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->event_type = 0; // 文件访问类型
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#endif
    
    return 0;
}


// 对应 struct container_event
// 需要结合cgroup信息，通常通过以下方式获取：
// - 通过bpf_get_current_cgroup_id()获取cgroup ID
// - 监控相关系统调用和资源使用
SEC("tp/sched/sched_process_fork")     // 容器内进程创建
int trace_sched_process_fork(struct trace_event_raw_sched_process_fork *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u64 zero = 0;
    struct container_event *event;
    
#ifdef OUTPUT_MODE_PERF_EVENT
    event = bpf_map_lookup_elem(&container_event_heap, &zero);
    if (!event)
        return 0;
#elif defined(OUTPUT_MODE_MAP_POLL)
    event = bpf_map_lookup_elem(&container_events, &zero);
    if (!event)
        return 0;
#else
    return 0;
#endif
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->cgroup_id = bpf_get_current_cgroup_id();
    event->event_type = 0; // 进程创建类型
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &container_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#elif defined(OUTPUT_MODE_MAP_POLL)
    __u64 key = event->timestamp;
    bpf_map_update_elem(&container_events, &key, event, BPF_ANY);
#endif
    
    return 0;
}

SEC("kprobe/cgroup_procs_write")       // cgroup进程管理
int trace_cgroup_procs_write(struct pt_regs *ctx) {
    __u64 id = bpf_get_current_pid_tgid();
    __u32 pid = id >> 32;
    
    // 如果设置了my_pid且当前进程不是目标进程，则跳过
    if (my_pid != 0 && my_pid != pid)
        return 0;
    
    // 获取事件结构体
    __u32 zero = 0;
    struct container_event *event = bpf_map_lookup_elem(&container_event_heap, &zero);
    if (!event)
        return 0;
    
    // 初始化事件
    __builtin_memset(event, 0, sizeof(*event));
    event->pid = pid;
    event->cgroup_id = bpf_get_current_cgroup_id();
    event->event_type = 2; // 资源管理类型
    event->timestamp = bpf_ktime_get_ns();
    bpf_get_current_comm(&event->comm, sizeof(event->comm));
    
    // 将事件提交到perf event数组
#ifdef OUTPUT_MODE_PERF_EVENT
    bpf_perf_event_output(ctx, &container_events, BPF_F_CURRENT_CPU, event, sizeof(*event));
#endif
    
    return 0;
}